
#ifndef TRITON_PIN_PYTHONBINDINGS_H
#define TRITON_PIN_PYTHONBINDINGS_H

#include <s2e/S2E.h>
#include <s2e/S2EExecutionState.h>

#include "xtypes.h"
#include "Instruction.h"

#include <map>
#include <set>
#include <vector>

//! The s2e namespace
namespace s2e {
  namespace plugins {
    extern PyMethodDef pluginsCallbacks[];
    PyObject* initplugins(void);
    namespace options {
      enum cb_kind {
        CB_AFTER,           //!< After the instruction processing.
        CB_BEFORE,          //!< Before the instruction processing.
        CB_FINI,            //!< At the end of the execution.
        CB_SYSCALL_ENTRY,   //!< Before the syscall processing.
        CB_SYSCALL_EXIT,    //!< After the syscall processing.
      };


      //! Callback called after the instruction processing.
      extern PyObject* callbackAfter;

      //! Callback called before the instruction processing.
      extern PyObject* callbackBefore;

      //! Callback called at the end of the execution.
      extern PyObject* callbackFini;

      //! Callback called before the syscall processing.
      extern PyObject* callbackSyscallEntry;

      //! Callback called after the syscall processing.
      extern PyObject* callbackSyscallExit;
    };

    //! The Callbacks namespace
    namespace callbacks {

      //! Callback called after the instruction processing.
      void after(S2EExecutionState *state, s2e::plugins::Instruction* inst);

      //! Callback called before the instruction processing.
      void before(S2EExecutionState *state, s2e::plugins::Instruction* inst);

      //! Callback called at the end of the execution.
      void fini(S2EExecutionState *state);

      //! Callback called before the syscall processing.
      void syscallEntry(S2EExecutionState *state, s2e::uint64 num);

      //! Callback called after the syscall processing.
      void syscallExit(S2EExecutionState *state, s2e::uint64 num);

   };

  };

};

#endif /* TRITON_PIN_PYTHONBINDINGS_H */
